<!DOCTYPE html>
<html lang="en">
  <head>
    <!-- Use correct character set. -->
    <meta charset="utf-8" />
    <!-- Tell IE to use the latest, best version. -->
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <!-- Make the application on mobile take up the full browser screen and disable user scaling. -->
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"
    />
    <title>Hello World!</title>
    <!-- <script src="../Build/Cesium/Cesium.js"></script> -->
    <script src="../Build/CesiumUnminified/Cesium.js"></script>
    <script src="jquery-2.0.3.js"></script>
    <style>
      @import url(../Build/Cesium/Widgets/widgets.css);

      html,
      body,
      #cesiumContainer {
        width: 100%;
        height: 100%;
        margin: 0;
        padding: 0;
        overflow: hidden;
      }
    </style>
  </head>

  <body>
    <div id="cesiumContainer"></div>
    <script>
      var DemoTileProvider = function DemoTileProvider() {
        this._quadtree = undefined;
        this._tilingScheme = new Cesium.GeographicTilingScheme();
        this._errorEvent = new Cesium.Event();
        this._levelZeroMaximumError = Cesium.QuadtreeTileProvider.computeDefaultLevelZeroMaximumGeometricError(
          this._tilingScheme
        );
        this.cartographicLimitRectangle = Cesium.Rectangle.clone(
          Cesium.Rectangle.MAX_VALUE
        );
        this._renderState = undefined;
        this._blendRenderState = undefined;
        this._tilesToRenderByTextureCount = [];
        this._commandList = [];
      };
      Object.defineProperties(Cesium, DemoTileProvider.prototype, {
        quadtree: {
          get: function () {
            return this._quadtree;
          },
          set: function (value) {
            this._quadtree = value;
          },
        },
        ready: {
          get: function () {
            return true;
          },
        },
        tilingScheme: {
          get: function () {
            return this._tilingScheme;
          },
        },
        errorEvent: {
          get: function () {
            return this._errorEvent;
          },
        },
      });
      var rectangleIntersectionScratch = new Cesium.Rectangle();
      var cornerPositionsScratch = [
        new Cesium.Cartesian3(),
        new Cesium.Cartesian3(),
        new Cesium.Cartesian3(),
        new Cesium.Cartesian3(),
      ];
      DemoTileProvider.prototype.update = function (frameState) {
        this._quadtree.beginFrame(frameState);
        this._quadtree.render(frameState);
        this._quadtree.endFrame(frameState);
      };
      DemoTileProvider.prototype.initialize = function (frameState) {};
      DemoTileProvider.prototype.beginUpdate = function (frameState) {
        // debugger
        // for (var i = 0; i < this._reTiles.length; i++) {
        //     var tile = this._reTiles[i];
        //     if (this.computeTileVisibility(tile, frameState, null) == Cesium.Visibility.NONE) {
        //         for (var key in frameState.context._pickObjects) {
        //             var obj = frameState.context._pickObjects[key];
        //             if (obj.id.indexOf('z' + tile.level + 'x' + tile.x + 'y' + tile.y + 'n') == 0) {
        //                 delete frameState.context._pickObjects[key];
        //             }
        //         }
        //     }
        // }
      };
      DemoTileProvider.prototype.endUpdate = function (frameState) {};

      DemoTileProvider.prototype.getLevelMaximumGeometricError = function (
        level
      ) {
        return this._levelZeroMaximumError / (1 << level);
      };
      DemoTileProvider.prototype.loadTile2 = function (frameState, tile) {
        (function (frameState, tile, that) {
          if (tile.state === Cesium.QuadtreeTileLoadState.START) {
            tile.data = {
              lines: [],
              geometryPrimitive: undefined,
            };
            var levelError = that.getLevelMaximumGeometricError(tile.level);
            if (tile.level < 16) {
              (function (frameState, tile) {
                fetch(
                  "http://192.168.1.40:8090/geoserver/gwc/service/wmts?REQUEST=GetTile&SERVICE=WMTS&VERSION=1.0.0&LAYER=swagger:_20200409064613_nanjing&STYLE=&TILEMATRIX=EPSG:4326:{z}&TILEMATRIXSET=EPSG:4326&FORMAT=application/json;type=geojson&TILECOL=" +
                    tile.x +
                    "&TILEROW=" +
                    tile.y +
                    ""
                )
                  .then(function (response) {
                    if (!response.ok) {
                      if (tile.count == undefined) {
                        tile.count = 0;
                      }
                      tile.count += 1;
                      if (tile.count >= 2) {
                        tile.state = Cesium.QuadtreeTileLoadState.DONE;
                        tile.renderable = true;
                        // return;
                      } else {
                        tile.state = Cesium.QuadtreeTileLoadState.START;
                      }
                      return;
                    }
                    var geometries = [];
                    for (var i = 0; i < 25; ++i) {
                      var positions = [];
                      var firstLongitude = Cesium.Math.lerp(
                        tile.rectangle.west,
                        tile.rectangle.east,
                        Math.random()
                      );
                      var firstLatitude = Cesium.Math.lerp(
                        tile.rectangle.south,
                        tile.rectangle.north,
                        Math.random()
                      );
                      var first = Cesium.Cartesian3.fromRadians(
                        firstLongitude,
                        firstLatitude
                      );
                      positions.push(first);
                      var lastLongitude = Cesium.Math.lerp(
                        tile.rectangle.west,
                        tile.rectangle.east,
                        Math.random()
                      );
                      var lastLatitude = Cesium.Math.lerp(
                        tile.rectangle.south,
                        tile.rectangle.north,
                        Math.random()
                      );
                      var last = Cesium.Cartesian3.fromRadians(
                        lastLongitude,
                        lastLatitude
                      );
                      positions.push(last);
                      var geometry = new Cesium.GeometryInstance({
                        geometry: Cesium.BoxGeometry.fromDimensions({
                          dimensions: new Cesium.Cartesian3(
                            Cesium.Math.nextRandomNumber() * 100,
                            Cesium.Math.nextRandomNumber() * 100,
                            Cesium.Math.nextRandomNumber() * 500
                          ),
                        }),
                        modelMatrix: Cesium.Matrix4.multiplyByTranslation(
                          Cesium.Transforms.eastNorthUpToFixedFrame(last),
                          new Cesium.Cartesian3(0.0, 0.0, 0),
                          new Cesium.Matrix4()
                        ),
                        //new Cesium.PolylineGeometry({
                        //    positions: positions,
                        //    vertexFormat: Cesium.PolylineMaterialAppearance.VERTEX_FORMAT
                        //})
                      });

                      geometries.push(geometry);
                    }

                    tile.data.geometryPrimitive = new Cesium.Primitive({
                      geometryInstances: geometries,
                      appearance: new Cesium.MaterialAppearance({
                        material: new Cesium.Material({
                          fabric: {
                            type: "Color",
                            uniforms: {
                              color: Cesium.Color.fromRandom({ alpha: 1.0 }),
                            },
                          },
                        }),
                        faceForward: true,
                        flat: false,
                      }),
                      shadows: Cesium.ShadowMode.ENABLED,
                    });

                    tile.state = Cesium.QuadtreeTileLoadState.LOADING;
                    if (tile.state === Cesium.QuadtreeTileLoadState.LOADING) {
                      tile.data.geometryPrimitive.update(frameState, []);
                      if (tile.data.geometryPrimitive._ready) {
                        tile.state = Cesium.QuadtreeTileLoadState.DONE;
                        tile.renderable = true;
                      }
                    }
                  })
                  .catch(function () {
                    // debugger
                    if (tile.count == undefined) {
                      tile.count = 0;
                    }
                    tile.count += 1;
                    if (tile.count >= 2) {
                      tile.state = Cesium.QuadtreeTileLoadState.DONE;
                      tile.renderable = true;
                      // return;
                    } else {
                      tile.state = Cesium.QuadtreeTileLoadState.START;
                    }
                  });
              })(frameState, tile);
              // Create random lines at the root level.
            } else {
              // Add more detail to parent lines at every other level.
              return;
            }

            tile.state = Cesium.QuadtreeTileLoadState.LOADING;
          }

          // if (tile.state === Cesium.QuadtreeTileLoadState.LOADING) {
          //     tile.data.geometryPrimitive.update(frameState, []);
          //     if (tile.data.geometryPrimitive._ready) {
          //         tile.state = Cesium.QuadtreeTileLoadState.DONE;
          //         tile.renderable = true;
          //     }
          // }
        })(frameState, tile, this);
      };
      DemoTileProvider.prototype.loadTile1 = function (frameState, tile) {
        // console.log('loadTile');
        // if (tile.state === Cesium.QuadtreeTileLoadState.START) {
        //     tile.data = {
        //         lines: [],
        //         geometryPrimitive: undefined
        //     };

        //     var levelError = this.getLevelMaximumGeometricError(tile.level);
        //     if (tile.level < 16) {
        //         // Create random lines at the root level.
        //         var geometries = [];
        //         for (var i = 0; i < 25; ++i) {
        //             var positions = [];
        //             var firstLongitude = Cesium.Math.lerp(tile.rectangle.west, tile.rectangle.east, Math
        //                 .random());
        //             var firstLatitude = Cesium.Math.lerp(tile.rectangle.south, tile.rectangle.north, Math
        //                 .random());
        //             var first = Cesium.Cartesian3.fromRadians(firstLongitude, firstLatitude);
        //             positions.push(first);
        //             var lastLongitude = Cesium.Math.lerp(tile.rectangle.west, tile.rectangle.east, Math
        //                 .random());
        //             var lastLatitude = Cesium.Math.lerp(tile.rectangle.south, tile.rectangle.north, Math
        //                 .random());
        //             var last = Cesium.Cartesian3.fromRadians(lastLongitude, lastLatitude);
        //             positions.push(last);
        //             var geometry = new Cesium.GeometryInstance({
        //                 geometry: Cesium.BoxGeometry.fromDimensions({
        //                     dimensions: new Cesium.Cartesian3(Cesium.Math.nextRandomNumber() * 100, Cesium.Math.nextRandomNumber() * 100, Cesium.Math.nextRandomNumber() * 500)
        //                 }),
        //                 modelMatrix: Cesium.Matrix4.multiplyByTranslation(Cesium.Transforms
        //                     .eastNorthUpToFixedFrame(last), new Cesium.Cartesian3(0.0, 0.0, 0),
        //                     new Cesium.Matrix4()),
        //                 //new Cesium.PolylineGeometry({
        //                 //    positions: positions,
        //                 //    vertexFormat: Cesium.PolylineMaterialAppearance.VERTEX_FORMAT
        //                 //})
        //             });

        //             geometries.push(geometry);
        //         }

        //         tile.data.geometryPrimitive = new Cesium.Primitive({
        //             geometryInstances: geometries,
        //             appearance: new Cesium.MaterialAppearance({
        //                 material: new Cesium.Material({
        //                     fabric: {
        //                         type: 'Color',
        //                         uniforms: {
        //                             color: Cesium.Color.fromRandom({ alpha: 1.0 })
        //                         }
        //                     }
        //                 }),
        //                 faceForward: true,
        //                 flat: false
        //             }),
        //             shadows: Cesium.ShadowMode.ENABLED
        //         });
        //     } else {
        //         // Add more detail to parent lines at every other level.
        //         return;
        //     }

        //     tile.state = Cesium.QuadtreeTileLoadState.LOADING;
        // }

        // if (tile.state === Cesium.QuadtreeTileLoadState.LOADING) {
        //     tile.data.geometryPrimitive.update(frameState, []);
        //     if (tile.data.geometryPrimitive._ready) {
        //         tile.state = Cesium.QuadtreeTileLoadState.DONE;
        //         tile.renderable = true;
        //     }
        // }
        tile.state = Cesium.QuadtreeTileLoadState.DONE;
        tile.renderable = true;
      };

      DemoTileProvider.prototype.loadTile = function (frameState, tile) {
        if (tile.state === Cesium.QuadtreeTileLoadState.START) {
          tile.data = {
            lines: [],
            geometryPrimitive: undefined,
          };

          var levelError = this.getLevelMaximumGeometricError(tile.level);
          if (tile.level < 16) {
            // Create random lines at the root level.
            var geometries = [];
            for (var i = 0; i < 25; ++i) {
              var positions = [];
              var firstLongitude = Cesium.Math.lerp(
                tile.rectangle.west,
                tile.rectangle.east,
                Math.random()
              );
              var firstLatitude = Cesium.Math.lerp(
                tile.rectangle.south,
                tile.rectangle.north,
                Math.random()
              );
              var first = Cesium.Cartesian3.fromRadians(
                firstLongitude,
                firstLatitude
              );
              positions.push(first);
              var lastLongitude = Cesium.Math.lerp(
                tile.rectangle.west,
                tile.rectangle.east,
                Math.random()
              );
              var lastLatitude = Cesium.Math.lerp(
                tile.rectangle.south,
                tile.rectangle.north,
                Math.random()
              );
              var last = Cesium.Cartesian3.fromRadians(
                lastLongitude,
                lastLatitude
              );
              positions.push(last);
              var geometry = new Cesium.GeometryInstance({
                geometry: Cesium.BoxGeometry.fromDimensions({
                  dimensions: new Cesium.Cartesian3(
                    Cesium.Math.nextRandomNumber() * 100,
                    Cesium.Math.nextRandomNumber() * 100,
                    Cesium.Math.nextRandomNumber() * 500
                  ),
                }),
                modelMatrix: Cesium.Matrix4.multiplyByTranslation(
                  Cesium.Transforms.eastNorthUpToFixedFrame(last),
                  new Cesium.Cartesian3(0.0, 0.0, 0),
                  new Cesium.Matrix4()
                ),
                //new Cesium.PolylineGeometry({
                //    positions: positions,
                //    vertexFormat: Cesium.PolylineMaterialAppearance.VERTEX_FORMAT
                //})
              });

              geometries.push(geometry);
            }

            // tile.data.geometryPrimitive = new Cesium.Primitive({
            //     geometryInstances: geometries,
            //     appearance: new Cesium.MaterialAppearance({
            //         material: new Cesium.Material({
            //             fabric: {
            //                 type: 'Color',
            //                 uniforms: {
            //                     color: Cesium.Color.fromRandom({ alpha: 1.0 })
            //                 }
            //             }
            //         }),
            //         faceForward: true,
            //         flat: false
            //     }),
            //     shadows: Cesium.ShadowMode.ENABLED
            // });

            tile.data.geometryPrimitive = new Cesium.Primitive({
              geometryInstances: geometries,
              appearance: new Cesium.MaterialAppearance({
                material: new Cesium.Material({
                  fabric: {
                    type: "Color",
                    uniforms: {
                      color: Cesium.Color.fromRandom({ alpha: 1.0 }),
                    },
                  },
                }),
                faceForward: true,
                flat: false,
              }),
              shadows: Cesium.ShadowMode.ENABLED,
            });
            computeTileVisibility();
          } else {
            // Add more detail to parent lines at every other level.
            return;
          }

          tile.state = Cesium.QuadtreeTileLoadState.LOADING;
        }

        if (tile.state === Cesium.QuadtreeTileLoadState.LOADING) {
          tile.data.geometryPrimitive.update(frameState, []);
          if (tile.data.geometryPrimitive._ready) {
            tile.state = Cesium.QuadtreeTileLoadState.DONE;
            tile.renderable = true;
          }
        }
      };
      DemoTileProvider.prototype.computeTileVisibility = function (
        tile,
        frameState,
        occluders
      ) {
        var distance = this.computeDistanceToTile(tile, frameState);
        tile._distance = distance;

        if (frameState.fog.enabled) {
          if (Cesium.Math.fog(distance, frameState.fog.density) >= 1.0) {
            // Tile is completely in fog so return that it is not visible.
            if (tile.data.geometryPrimitive) {
              // console.log('none')
              tile.data = undefined;
            }
            return Cesium.Visibility.NONE;
          }
        }

        var surfaceTile = tile.data;
        var tileBoundingRegion = surfaceTile.tileBoundingRegion;

        if (surfaceTile.boundingVolumeSourceTile === undefined) {
          // We have no idea where this tile is, so let's just call it partially visible.
          return Cesium.Visibility.PARTIAL;
        }

        var cullingVolume = frameState.cullingVolume;
        var boundingVolume = surfaceTile.orientedBoundingBox;

        if (!boundingVolume && surfaceTile.renderedMesh) {
          boundingVolume = surfaceTile.renderedMesh.boundingSphere3D;
        }

        // Check if the tile is outside the limit area in cartographic space
        surfaceTile.clippedByBoundaries = false;
        var clippedCartographicLimitRectangle = clipRectangleAntimeridian(
          tile.rectangle,
          this.cartographicLimitRectangle
        );
        var areaLimitIntersection = Cesium.Rectangle.simpleIntersection(
          clippedCartographicLimitRectangle,
          tile.rectangle,
          rectangleIntersectionScratch
        );
        if (!areaLimitIntersection) {
          if (tile.data.geometryPrimitive) {
            // console.log('none')
            // tile.data = undefined;
          }
          return Cesium.Visibility.NONE;
        }
        if (!Cesium.Rectangle.equals(areaLimitIntersection, tile.rectangle)) {
          surfaceTile.clippedByBoundaries = true;
        }

        if (frameState.mode !== Cesium.SceneMode.SCENE3D) {
          boundingVolume = boundingSphereScratch;
          BoundingSphere.fromRectangleWithHeights2D(
            tile.rectangle,
            frameState.mapProjection,
            tileBoundingRegion.minimumHeight,
            tileBoundingRegion.maximumHeight,
            boundingVolume
          );
          Cartesian3.fromElements(
            boundingVolume.center.z,
            boundingVolume.center.x,
            boundingVolume.center.y,
            boundingVolume.center
          );

          if (
            frameState.mode === SceneMode.MORPHING &&
            surfaceTile.renderedMesh
          ) {
            boundingVolume = BoundingSphere.union(
              surfaceTile.renderedMesh.boundingSphere3D,
              boundingVolume,
              boundingVolume
            );
          }
        }

        if (!boundingVolume) {
          return Cesium.Intersect.INTERSECTING;
        }

        var clippingPlanes = this._clippingPlanes;
        if (clippingPlanes && clippingPlanes.enabled) {
          var planeIntersection = clippingPlanes.computeIntersectionWithBoundingVolume(
            boundingVolume
          );
          tile.isClipped = planeIntersection !== Intersect.INSIDE;
          if (planeIntersection === Cesium.Intersect.OUTSIDE) {
            if (tile.data.geometryPrimitive) {
              // console.log('none')
              tile.data = undefined;
            }
            return Cesium.Visibility.NONE;
          }
        }

        var intersection = cullingVolume.computeVisibility(boundingVolume);
        if (intersection === Cesium.Intersect.OUTSIDE) {
          if (tile.data.geometryPrimitive) {
            // console.log('none')
            // tile.data = undefined;
          }
          return Cesium.Visibility.NONE;
        }

        var ortho3D =
          frameState.mode === Cesium.SceneMode.SCENE3D &&
          frameState.camera.frustum instanceof Cesium.OrthographicFrustum;
        if (
          frameState.mode === Cesium.SceneMode.SCENE3D &&
          !ortho3D &&
          occluders
        ) {
          var occludeePointInScaledSpace =
            surfaceTile.occludeePointInScaledSpace;
          if (!occludeePointInScaledSpace) {
            return intersection;
          }

          if (
            occluders.ellipsoid.isScaledSpacePointVisible(
              occludeePointInScaledSpace
            )
          ) {
            return intersection;
          }

          if (tile.data.geometryPrimitive) {
            // console.log('none')
            // tile.data = undefined;
          }
          return Cesium.Visibility.NONE;
        }

        return intersection;
      };
      DemoTileProvider.prototype.canRefine = function (
        tile,
        frameState,
        occluders
      ) {
        if (tile.level < 16) return true;
        return false;
      };
      DemoTileProvider.prototype.showTileThisFrame = function (
        tile,
        context,
        frameState,
        commandList
      ) {
        if (tile.data.geometryPrimitive) {
          // context.passes.pick = true
          tile.data.geometryPrimitive.update(context, frameState, commandList);
        }
      };
      DemoTileProvider.prototype.computeDistanceToTile = function (
        tile,
        frameState
      ) {
        // The distance should be:
        // 1. the actual distance to the tight-fitting bounding volume, or
        // 2. a distance that is equal to or greater than the actual distance to the tight-fitting bounding volume.
        //
        // When we don't know the min/max heights for a tile, but we do know the min/max of an ancestor tile, we can
        // build a tight-fitting bounding volume horizontally, but not vertically. The min/max heights from the
        // ancestor will likely form a volume that is much bigger than it needs to be. This means that the volume may
        // be deemed to be much closer to the camera than it really is, causing us to select tiles that are too detailed.
        // Loading too-detailed tiles is super expensive, so we don't want to do that. We don't know where the child
        // tile really lies within the parent range of heights, but we _do_ know the child tile can't be any closer than
        // the ancestor height surface (min or max) that is _farthest away_ from the camera. So if we compute distance
        // based that conservative metric, we may end up loading tiles that are not detailed enough, but that's much
        // better (faster) than loading tiles that are too detailed.
        var heightSource = updateTileBoundingRegion(
          tile,
          this.terrainProvider,
          frameState
        );
        var surfaceTile = tile.data;
        var tileBoundingRegion = surfaceTile.tileBoundingRegion;

        if (heightSource === undefined) {
          // Can't find any min/max heights anywhere? Ok, let's just say the
          // tile is really far away so we'll load and render it rather than
          // refining.
          return 9999999999.0;
        } else if (surfaceTile.boundingVolumeSourceTile !== heightSource) {
          // Heights are from a new source tile, so update the bounding volume.
          surfaceTile.boundingVolumeSourceTile = heightSource;

          var rectangle = tile.rectangle;
          if (
            rectangle &&
            rectangle.width < Cesium.Math.PI_OVER_TWO + Cesium.Math.EPSILON5
          ) {
            surfaceTile.orientedBoundingBox = Cesium.OrientedBoundingBox.fromRectangle(
              tile.rectangle,
              tileBoundingRegion.minimumHeight,
              tileBoundingRegion.maximumHeight,
              tile.tilingScheme.ellipsoid,
              surfaceTile.orientedBoundingBox
            );

            surfaceTile.occludeePointInScaledSpace = computeOccludeePoint(
              this,
              surfaceTile.orientedBoundingBox.center,
              tile.rectangle,
              tileBoundingRegion.maximumHeight,
              surfaceTile.occludeePointInScaledSpace
            );
          }
        }

        var min = tileBoundingRegion.minimumHeight;
        var max = tileBoundingRegion.maximumHeight;

        if (surfaceTile.boundingVolumeSourceTile !== tile) {
          var cameraHeight = frameState.camera.positionCartographic.height;
          var distanceToMin = Math.abs(cameraHeight - min);
          var distanceToMax = Math.abs(cameraHeight - max);
          if (distanceToMin > distanceToMax) {
            tileBoundingRegion.minimumHeight = min;
            tileBoundingRegion.maximumHeight = min;
          } else {
            tileBoundingRegion.minimumHeight = max;
            tileBoundingRegion.maximumHeight = max;
          }
        }

        var result = tileBoundingRegion.distanceToCamera(frameState);

        tileBoundingRegion.minimumHeight = min;
        tileBoundingRegion.maximumHeight = max;

        return result;
      };

      function updateTileBoundingRegion(tile, terrainProvider, frameState) {
        var surfaceTile = tile.data;
        if (surfaceTile === undefined) {
          surfaceTile = tile.data = new Cesium.GlobeSurfaceTile();
        }

        if (surfaceTile.tileBoundingRegion === undefined) {
          surfaceTile.tileBoundingRegion = new Cesium.TileBoundingRegion({
            computeBoundingVolumes: false,
            rectangle: tile.rectangle,
            ellipsoid: tile.tilingScheme.ellipsoid,
            minimumHeight: 0.0,
            maximumHeight: 0.0,
          });
        }
        return tile;
      }

      function clipRectangleAntimeridian(
        tileRectangle,
        cartographicLimitRectangle
      ) {
        if (cartographicLimitRectangle.west < cartographicLimitRectangle.east) {
          return cartographicLimitRectangle;
        }
        var splitRectangle = Rectangle.clone(
          cartographicLimitRectangle,
          splitCartographicLimitRectangleScratch
        );
        var tileCenter = Rectangle.center(
          tileRectangle,
          rectangleCenterScratch
        );
        if (tileCenter.longitude > 0.0) {
          splitRectangle.east = CesiumMath.PI;
        } else {
          splitRectangle.west = -CesiumMath.PI;
        }
        return splitRectangle;
      }

      function computeOccludeePoint(
        tileProvider,
        center,
        rectangle,
        height,
        result
      ) {
        var ellipsoidalOccluder = tileProvider.quadtree._occluders.ellipsoid;
        var ellipsoid = ellipsoidalOccluder.ellipsoid;

        var cornerPositions = cornerPositionsScratch;
        Cesium.Cartesian3.fromRadians(
          rectangle.west,
          rectangle.south,
          height,
          ellipsoid,
          cornerPositions[0]
        );
        Cesium.Cartesian3.fromRadians(
          rectangle.east,
          rectangle.south,
          height,
          ellipsoid,
          cornerPositions[1]
        );
        Cesium.Cartesian3.fromRadians(
          rectangle.west,
          rectangle.north,
          height,
          ellipsoid,
          cornerPositions[2]
        );
        Cesium.Cartesian3.fromRadians(
          rectangle.east,
          rectangle.north,
          height,
          ellipsoid,
          cornerPositions[3]
        );

        return ellipsoidalOccluder.computeHorizonCullingPoint(
          center,
          cornerPositions,
          result
        );
      }
      DemoTileProvider.prototype.isDestroyed = function () {
        return false;
      };
      DemoTileProvider.prototype.updateForPick = function (frameState) {
        // var drawCommands = this._drawCommands;
        // for (var i = 0, length = this._usedDrawCommands; i < length; ++i) {
        // frameState.commandList.push(drawCommands[i]);
        // }
        frameState.commandList = this._commandList;
      };
      DemoTileProvider.prototype.destroy = function () {
        return Cesium.destroyObject(this);
      };
      // var viewer = new Cesium.Viewer('cesiumContainer');
      var viewer = new Cesium.Viewer("cesiumContainer", {
        //需要进行可视化的数据源的集合
        animation: false, //是否显示动画控件
        shouldAnimate: true,
        homeButton: false, //是否显示Home按钮
        fullscreenButton: false, //是否显示全屏按钮
        baseLayerPicker: false, //是否显示图层选择控件
        geocoder: false, //是否显示地名查找控件
        timeline: false, //是否显示时间线控件
        sceneModePicker: true, //是否显示投影方式控件
        navigationHelpButton: false, //是否显示帮助信息控件
        infoBox: false, //是否显示点击要素之后显示的信息
        requestRenderMode: true, //启用请求渲染模式
        scene3DOnly: false, //每个几何实例将只能以3D渲染以节省GPU内存
        sceneMode: 3, //初始场景模式 1 2D模式 2 2D循环模式 3 3D模式  Cesium.SceneMode
        fullscreenElement: document.body, //全屏时渲染的HTML元素 暂时没发现用处
        selectionIndicator: true,
        infoBox: true,
        //天地图是官方开元的地图，不需要密钥
        imageryProvider: new Cesium.UrlTemplateImageryProvider({
          url:
            "http://mt1.google.cn/vt/lyrs=s&hl=zh-CN&x={x}&y={y}&z={z}&s=Gali",
        }),
      });

      var scene = viewer.scene;
      var primitives = scene.primitives;

      var prim = new Cesium.QuadtreePrimitivezh({
        tileProvider: new DemoTileProvider(),
      });
      primitives.add(prim);

      var rectangleInstance = new Cesium.GeometryInstance({
        geometry: new Cesium.RectangleGeometry({
          rectangle: Cesium.Rectangle.fromDegrees(-140.0, 30.0, -100.0, 40.0),
          vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT,
        }),
        attributes: {
          color: new Cesium.ColorGeometryInstanceAttribute(0.0, 1.0, 1.0, 0.5),
        },
      });
      var ellipsoidInstance = new Cesium.GeometryInstance({
        geometry: new Cesium.EllipsoidGeometry({
          radii: new Cesium.Cartesian3(500000.0, 500000.0, 1000000.0),
          vertexFormat: Cesium.VertexFormat.POSITION_AND_NORMAL,
        }),
        modelMatrix: Cesium.Matrix4.multiplyByTranslation(
          Cesium.Transforms.eastNorthUpToFixedFrame(
            Cesium.Cartesian3.fromDegrees(-95.59777, 40.03883)
          ),
          new Cesium.Cartesian3(0.0, 0.0, 500000.0),
          new Cesium.Matrix4()
        ),
        attributes: {
          color: Cesium.ColorGeometryInstanceAttribute.fromColor(
            Cesium.Color.AQUA
          ),
        },
      });
      scene.primitives.add(
        new Cesium.Primitive({
          geometryInstances: [rectangleInstance, ellipsoidInstance],
          appearance: new Cesium.PerInstanceColorAppearance(),
        })
      );

      var k = 0;
      Cesium.Scene.prototype.screenToWorld = L;
      function L(t, n) {
        if (viewer.canvas.width <= 0 || viewer.canvas.height <= 0) return;
        if (k > 0) return;
        var r = {
          level: 16,
          callback: function (s) {
            console.log(s);
          },
          pickPrimitive: undefined,
          pick: undefined,
          includeUndergroundSurface: !0,
        };
        var i = $.extend(!0, {}, r, n);
        var s;
        var o;
        try {
          k++;
          o = viewer.scene.pick(t);
        } catch (u) {
          console.log("Pick error!");
        } finally {
          k--;
        }
        var a =
          i.includeUndergroundSurface &&
          Cesium.defined(o) &&
          Cesium.defined(o.id) &&
          o.id == "undergroundSurface";
        if (
          Cesium.defined(o) &&
          Cesium.defined(o.primitive) &&
          viewer.scene.pickPositionSupported
        )
          viewer.scene.pickTranslucentDepth &&
            o.primitive._appearance &&
            o.primitive._appearance.translucent &&
            C(),
            (s = viewer.scene.pickPosition(t)),
            i.callback != undefined && i.callback(s);
        // else if (viewer.scene.pickPositionSupported)
        //     s = viewer.scene.pickPosition(t),
        //         i.callback != undefined && i.callback(s);
        else {
          var f = viewer.camera.getPickRay(t);
          s = viewer.scene.globe.pick(f, viewer.scene);
          if (i.callback != undefined) {
            var l = viewer.scene.globe.ellipsoid.cartesianToCartographic(s),
              c = Cesium.sampleTerrain(viewer.terrainProvider, i.level, [l]);
            Cesium.when(c, function (e) {
              e[0].height != undefined &&
                (s = viewer.scene.globe.ellipsoid.cartographicToCartesian(
                  e[0]
                )),
                i.callback(s);
            });
          }
        }
        return (
          n != undefined &&
            o != undefined &&
            ((n.pickPrimitive = o.primitive), (n.id = o.id), (n.pick = o)),
          s
        );
      }
      var handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
      handler.setInputAction(function (e) {
        var n = {};
        // viewer.scene.screenToWorld(e.position, n);
      }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
    </script>
  </body>
</html>
